package rjeutsky.xml.dom;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import rjeutsky.models.OldCard;
import rjeutsky.xml.OldCardFileSerializer;
import rjeutsky.xml.common.Constants;

public class OldCardDomSerializer implements OldCardFileSerializer {

	private List<OldCard> cards;
	private String filePath;
	
	@Override
	public boolean deserializeFromFile() {
		try {
			File file = new File(filePath);
			Document document = getDocument(file);
			DocumentTransformer transformer = new DocumentTransformer();
			transformer.setDocument(document);
			transformer.readDocument();
			cards = transformer.getCards();
			return true;
		} catch (IOException e) {
			System.err.println(e.getMessage());
		} catch (SAXException e) {
			System.err.println(e.getMessage());
		} catch (ParserConfigurationException e) {
			System.err.println(e.getMessage());
		}
		
		return false;
	}
	
	protected Document getDocument(File file) throws ParserConfigurationException, SAXException, IOException {
		SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File(Constants.SCHEMA_PATH));
		Document document;
		DocumentBuilderFactory factory = DocumentBuilderFactory
				.newInstance();
		factory.setIgnoringComments(true);
		factory.setSchema(schema);
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		document = builder.parse(file);
		return document;
	}

	@Override
	public boolean serializeToFile() {
		try {
			DocumentTransformer transformer = new DocumentTransformer();
			transformer.setCards(cards);
			transformer.writeDocument();
			saveXml(transformer.getDocument());
			return true;
		} catch (IOException e){
			System.err.println(e.getMessage());
		} catch (TransformerException e) {
			System.err.println(e.getMessage());
		} catch (ParserConfigurationException e) {
			System.err.println(e.getMessage());
		}
		
		return false;
	}
	
	private void saveXml(Document xml) throws IOException,
		TransformerException {
		File file = new File(filePath);
		FileWriter fWriter = new FileWriter(file);
		TransformerFactory.newInstance().newTransformer()
				.transform(new DOMSource(xml), new StreamResult(fWriter));
		fWriter.close();
	} 
	
	@Override
	public String getInfo() {
		return "Writes with DOM, reads with DOM";
	}
	
	@Override
	public String getFilePath() {
		return filePath;
	}

	@Override
	public void setFilePath(String path) {
		this.filePath = path;
	}

	@Override
	public void setOldCardList(List<OldCard> list) {
		this.cards = list;
	}
	
	@Override
	public List<OldCard> getOldCardList() {
		return cards;
	}

}
